package cn.com.anypay.manager.payment.controller;

import cn.com.anypay.manager.payment.dto.PaymentRequestDTO;
import cn.com.anypay.manager.payment.dto.PaymentResultDTO;
import cn.com.anypay.manager.payment.service.PaymentService;
import cn.com.anypay.manager.payment.core.PaymentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/payment/test")
public class PaymentTestController {
    private static final Logger logger = LoggerFactory.getLogger(PaymentTestController.class);

    @Autowired
    private PaymentService paymentService;

    // ================== 渠道信息相关接口 ==================

    /**
     * 获取所有可用渠道ID
     */
    @GetMapping("/channels")
    public Map<String, Object> getAvailableChannels() {
        logger.info("获取所有可用渠道ID");

        try {
            String[] channelIds = paymentService.getAvailableChannelIds();
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", channelIds);
            return result;
        } catch (Exception e) {
            logger.error("获取渠道ID失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    /**
     * 获取指定渠道信息
     */
    @GetMapping("/channels/{channelId}")
    public Map<String, Object> getChannelInfo(@PathVariable String channelId) {
        logger.info("获取渠道信息: {}", channelId);

        try {
            var channelInfo = paymentService.getChannelInfo(channelId);
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", channelInfo);
            return result;
        } catch (Exception e) {
            logger.error("获取渠道信息失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    /**
     * 获取所有渠道的增强信息
     */
    @GetMapping("/channels/enhanced")
    public Map<String, Object> getAllEnhancedChannelInfo() {
        logger.info("获取所有渠道的增强信息");

        try {
            var enhancedInfos = paymentService.getAllEnhancedChannelInfo();
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", enhancedInfos);
            return result;
        } catch (Exception e) {
            logger.error("获取增强渠道信息失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

        /**
     * 获取所有渠道实现信息（按注册顺序）
     */
    @GetMapping("/channels/implementations/ordered")
    public Map<String, Object> getAllChannelImplementationInfo() {
        logger.info("获取所有渠道实现信息（按注册顺序）");

        try {
            var implementations = paymentService.getAllChannelImplementationInfoInOrder();
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", implementations);
            return result;
        } catch (Exception e) {
            logger.error("获取渠道实现信息失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    /**
     * 获取支付产品列表
     */
    @GetMapping("/products")
    public Map<String, Object> getPayProducts() {
        logger.info("获取支付产品列表");

        try {
            // 这里可以返回所有支持的支付产品
            String[] products = {"NATIVE", "JSAPI", "H5", "APP", "WEB", "QR", "MWEB", "SCAN"};
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", products);
            return result;
        } catch (Exception e) {
            logger.error("获取支付产品列表失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    /**
     * 获取框架信息
     */
    @GetMapping("/info")
    public Map<String, Object> getFrameworkInfo() {
        logger.info("获取框架信息");

        try {
            Map<String, Object> info = new HashMap<>();
            info.put("framework", "AnyPay 支付渠道抽象框架");
            info.put("version", "1.0.0");
            info.put("author", "AnyPay Team");
            info.put("date", "2025-01-05");

            // 获取统计信息
            String[] channelIds = paymentService.getAvailableChannelIds();
            var implementations = paymentService.getAllChannelImplementationInfoInOrder();

            info.put("channelCount", channelIds.length);
            info.put("implementationCount", implementations.length);
            info.put("availableCount", java.util.Arrays.stream(implementations)
                .mapToInt(impl -> impl.isAvailable() ? 1 : 0)
                .sum());

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", info);
            return result;
        } catch (Exception e) {
            logger.error("获取框架信息失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    // ================== 支付测试相关接口 ==================

    @PostMapping("/simulate")
    public Map<String, Object> simulatePayments() throws PaymentException {
        logger.info("=== 开始模拟支付测试 ===");

        Map<String, Object> result = new HashMap<>();

        // 1. 使用 channeltest1 的 impl1 实现 - NATIVE 支付产品
        logger.info("--- 测试 ChannelTest1-Impl1 NATIVE 支付 ---");
        PaymentRequestDTO request1 = createTestRequest("ORDER001", "channeltest1", "impl1", "NATIVE", new BigDecimal("100.00"));
        PaymentResultDTO result1 = paymentService.createPayment(request1);
        result.put("channeltest1_impl1_native", result1);
        logger.info("ChannelTest1-Impl1 NATIVE 支付结果: {}", result1.getStatus());

        // 2. 使用 channeltest1 的 impl2 实现 - JSAPI 支付产品
        logger.info("--- 测试 ChannelTest1-Impl2 JSAPI 支付 ---");
        PaymentRequestDTO request2 = createTestRequest("ORDER002", "channeltest1", "impl2", "JSAPI", new BigDecimal("150.00"));
        PaymentResultDTO result2 = paymentService.createPayment(request2);
        result.put("channeltest1_impl2_jsapi", result2);
        logger.info("ChannelTest1-Impl2 JSAPI 支付结果: {}", result2.getStatus());

        // 3. 使用 channeltest2 的 default 实现 - APP 支付产品
        logger.info("--- 测试 ChannelTest2-Default APP 支付 ---");
        PaymentRequestDTO request3 = createTestRequest("ORDER003", "channeltest2", "default", "APP", new BigDecimal("200.00"));
        PaymentResultDTO result3 = paymentService.createPayment(request3);
        result.put("channeltest2_default_app", result3);
        logger.info("ChannelTest2-Default APP 支付结果: {}", result3.getStatus());

        result.put("success", true);
        result.put("message", "模拟支付测试完成");

        logger.info("=== 模拟支付测试结束 ===");
        return result;
    }

    @PostMapping("/simulate/{channelId}/{implType}/{payProduct}")
    public Map<String, Object> simulateSpecificPayment(
            @PathVariable String channelId,
            @PathVariable String implType,
            @PathVariable String payProduct,
            @RequestParam(defaultValue = "100.00") String amount) throws PaymentException {

        logger.info("=== 开始指定渠道支付测试 ===");
        logger.info("渠道: {}, 实现类型: {}, 支付产品: {}, 金额: {}", channelId, implType, payProduct, amount);

        String orderId = "ORDER_" + System.currentTimeMillis();
        PaymentRequestDTO request = createTestRequest(orderId, channelId, implType, payProduct, new BigDecimal(amount));
        PaymentResultDTO paymentResult = paymentService.createPayment(request);

        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("orderId", orderId);
        result.put("channelId", channelId);
        result.put("implType", implType);
        result.put("payProduct", payProduct);
        result.put("amount", amount);
        result.put("paymentResult", paymentResult);

        logger.info("指定渠道支付测试完成: {}", paymentResult.getStatus());
        logger.info("=== 指定渠道支付测试结束 ===");
        return result;
    }

    /**
     * 创建支付订单
     */
    @PostMapping("/create")
    public Map<String, Object> createPayment(@RequestBody PaymentRequestDTO request) throws PaymentException {
        logger.info("=== 创建支付订单 ===");
        logger.info("订单ID: {}, 渠道: {}, 实现类型: {}, 支付产品: {}, 金额: {}",
                request.getMerchantOrderId(), request.getChannelId(), request.getImplementationType(),
                request.getPayProduct(), request.getAmount());

        try {
            PaymentResultDTO paymentResult = paymentService.createPayment(request);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("data", paymentResult);

            logger.info("支付订单创建成功: {}", paymentResult.getStatus());
            logger.info("=== 创建支付订单结束 ===");
            return result;
        } catch (Exception e) {
            logger.error("创建支付订单失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
    }

    private PaymentRequestDTO createTestRequest(String orderId, String channelId, String implType, String payProduct, BigDecimal amount) {
        PaymentRequestDTO request = new PaymentRequestDTO();
        request.setMerchantOrderId(orderId);
        request.setChannelId(channelId);
        request.setImplementationType(implType);  // 指定实现类型
        request.setPayProduct(payProduct);
        request.setAmount(amount);
        request.setCurrency("CNY");
        request.setSubject("测试商品-" + channelId + "-" + implType + "-" + payProduct);
        request.setBody("这是一个测试支付订单");
        request.setNotifyUrl("http://localhost:8080/api/payment/notify");
        request.setReturnUrl("http://localhost:8080/api/payment/return");
        return request;
    }
}